<template>
  <el-upload
    ref="uploadForm"
    v-model="fileLists"
    :method="method"
    :action="action"
    :multiple="multiple"
    :accept="accept"
    :list-type="listType"
    :auto-upload="autoUpload"
    :drag="drag"
    :limit="limit"
    :show-file-list="showFileList"
    :disabled="disabled || fileList.length >= limit"
    :on-success="onSuccess"
    :on-error="onError"
    :on-change="onChange"
    :on-exceed="onExceed"
    :before-upload="beforeUpload"
    :before-remove="beforeRemove"
    v-bind="attrs"
  >
    <template v-if="listType === 'text'" #trigger>
      <el-button type="primary">{{ textFont }}</el-button>
    </template>
    <el-icon v-if="fileList.length < limit && listType != 'text'"
      ><Plus
    /></el-icon>
    <template #file="{ file }">
      <div>
        <img class="el-upload-list__item-thumbnail" :src="file.url" alt=""></img>
        <span class="el-upload-list__item-actions">
          <span
            class="el-upload-list__item-preview"
            @click="handlePreview(file)"
          >
            <el-icon><zoom-in /></el-icon>
          </span>
          <span
            class="el-upload-list__item-delete"
            @click="handleDownload(file)"
          >
            <el-icon><Download /></el-icon>
          </span>
          <span
            v-if="file.status !== 'success'"
            class="el-upload-list__item-delete"
            @click="handleRemove(file)"
          >
            <el-icon><Delete /></el-icon>
          </span>
        </span>
      </div>
    </template>
  </el-upload>

  <el-dialog v-model="previewVisible" width="70%">
    <img
      w-full
      :src="previewUrl"
      style="width: 100%; max-height: 500px; overflow: auto"
      alt="Preview Image"
    ></img>
  </el-dialog>
</template>

<script setup lang="ts" name="BaseUpload">
import { ref, computed, useAttrs } from "vue";
import { Delete, Download, Plus, ZoomIn } from "@element-plus/icons-vue";
import type { UploadFile, UploadFiles, UploadInstance } from "element-plus";
import { ElMessage as message, ElNotification as NOT } from "element-plus";
let props = withDefaults(
  defineProps<{
    fileList: any;
    // 请求的url
    action: string;
    // 请求方法
    method?: string;
    // 是否支持多选
    multiple?: boolean;
    // 是否启用拖拽上传
    drag?: boolean;
    // 上传文件类型
    accept?: string;
    // 上传样式 'text' | 'picture' | 'picture-card'
    listType: string;
    // 当listType等于text时有效
    textFont?: string;
    // 是否开启自动上传
    autoUpload: boolean;
    // 是否显示已上传文件
    showFileList: boolean;
    // 允许上传的最大文件数量
    limit: number;
    // 是否禁用上传
    disabled?: boolean;
    // 文件上传大小
    maxSize: number;
    // 不允许重名文件上传
    repetitionName?: boolean;
  }>(),
  {
    fileList: [],
    method: "post",
    action: "",
    limit: 3,
    disabled: false,
    autoUpload: false,
    listType: "picture-card",
    drag: false,
    multiple: true,
    maxSize: 5 * 1024 * 1024,
    repetitionName: true,
    showFileList: true,
  }
);

let emit = defineEmits([
  "change",
  "uploadSuccess",
  "uploadError",
  "beforeUpload",
  "beforeRemove",
  "httpRequest",
  "uploadExceed",
  "update:fileList",
]);

let attrs = useAttrs();

let fileLists = computed({
  get: () => props.fileList,
  set: (value: string) => emit("update:fileList", value),
});

let previewVisible = ref(false);
let previewUrl = ref("");

// 上传成功
let onSuccess = (res: any, file: UploadFile, files: UploadFiles) => {
  console.log(1);
  emit("uploadSuccess", res, file, files);
};

// 上传失败
let onError = (err: any, file: UploadFile, files: UploadFiles) => {
  console.log(err, "上传遇到了错误");
  emit("uploadError", err, file, files);
};

// 文件状态变化(添加上传|上传成功|上传失败都会调用)
let onChange = (file: UploadFile, files: UploadFiles) => {
  if ((file.size as number) > props.maxSize) {
    NOT({
      title: "系统消息",
      type: "warning",
      message: `
      上传文件大小为${((file.size as number) / 1024).toFixed(2)}kb
      已超出规定上传大小${(props.maxSize / 1024).toFixed(2)}kb限制`,
    });
    files.forEach((item: UploadFile, index: number) => {
      if (item.uid === file.uid) {
        files.splice(index, 1);
      }
    });
  }
  if (props.repetitionName && file.status === "ready") {
    let resule = props.fileList.some((item: UploadFile) => {
      return item.name === file.name;
    });
    if (resule) {
      NOT({
        title: "系统消息",
        type: "warning",
        message: `文件${file.name}上传失败、已存在相同文件`,
      });
      files.forEach((item: UploadFile, index: number) => {
        if (item.uid === file.uid) {
          files.splice(index, 1);
        }
      });
    }
  }
  console.log(file, 3);
  emit("update:fileList", files);
  emit("change", file);
};

// 上传文件数量超出限制
let onExceed = (file: UploadFile[], files: UploadFile[]) => {
  console.log(4);
  emit("uploadExceed", file, files);
};

// 上传之前调用
let beforeUpload = (file: UploadFile) => {
  console.log(file, props.action);
  emit("beforeUpload", file);
  return true;
};

// 删除之前调用
let beforeRemove = (file: UploadFile[], files: UploadFile[]) => {
  console.log(6);
  emit("beforeRemove", file, files);
};

// 手动移除上传文件
let handleRemove = (file: UploadFile) => {
  props.fileList.forEach((item: UploadFile, index: number) => {
    if (item.uid === file.uid) {
      props.fileList.splice(index, 1);
    }
  });
};

// 预览
let handlePreview = (file: UploadFile) => {
  previewUrl.value = file.url as string;
  previewVisible.value = true;
};

// 下载
let handleDownload = (file: UploadFile) => {
  let link: any = document.createElement("a");
  link.href = file.url as string;
  link.download = file.name;
  document.body.append(link);
  link.click();
  link.remove();
};
</script>

<style lang="less" scoped>
.container {
}
</style>
